
//https://www.acwing.com/problem/content/908/


//将左端点排序(升序) 
//从前往后处理每一个区间
//判断每个区间是否能将其放到某个现有区间中(判断某个区间的右端点在不在某个现有组的左端点的右侧,开始已排序)
//L[i]>max_r(每个组所有区间最右边的最大值)
//如果不存在这样的组,开个新的组
//如果存在,将他放到这个组,在更新下当前组的max_r


//堆的做法
#include<bits/stdc++.h>
using namespace std;
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
const int N=1e5+10;
#define INF 0x3f3f3f3f;
typedef long long int ll;
#define close(); std::ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
//----------------------------------------------------------------------------//
int n;
struct Range
{
    int l, r;
    bool operator< (const Range &W)const
    {
        return l < W.l;//当前小于比较的
    }
}range[N];

int main()
{
	close();
    cin>>n;
    for (int i = 0; i < n; i ++ ) cin>>range[i].l>>range[i].r;

    sort(range, range + n);

    priority_queue<int,vector<int>,greater<int>> heap;//小根堆

    for(int i=0;i<n;i++)
    {
    	auto r=range[i];
    	if(heap.empty()||heap.top()>=r.l) heap.push(r.r);//不满足要求开新组
    	else//满足要求
    	{
    		int t=heap.top();
    		heap.pop();
    		heap.push(r.r);
 
    	}
    }

    cout<<heap.size()<<'\n';

    return 0;
}